﻿// Copyright (c) 2012 - 2021 Jared Zheng <jaredz at outlook dot com>
// Buddha Framework is licensed under Mulan PSL v2.
// You can use this software according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of Mulan PSL v2 at:
//          http://license.coscl.org.cn/MulanPSL2
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
// See the Mulan PSL v2 for more details.
//
// Create : 2012-12-01 version 0.1 Jared Zheng <jaredz at outlook dot com>
// Update : 2021-03-19 version 4.0.0 Jared Zheng <jaredz at outlook dot com>

#ifndef __MASTER_SERVER_H__
#define __MASTER_SERVER_H__

#pragma once

#include "CommonPacket.h"
#include "CommonServer.h"

///////////////////////////////////////////////////////////////////////////////////////////////////////////
// master
class CMasterServer : public ICommonFrame, public CPAKHandler
{
public:
    enum CHECK_TIME
    {
        // 每隔特点时间检测更新线程状态, 定时器周期为更新周期
        CHECK_TIME_ID = 1001,
    };
public:
    CSignalEvent Events; // 业务层事件信号
public:
    CMasterServer(void);
    virtual ~CMasterServer(void);
    // CComponent
    virtual UInt   Command(PCXStr pszCMD, uintptr_t utParam) OVERRIDE;
    virtual UInt   Update(void) OVERRIDE;
    // ICommonFrame
    virtual UInt   Init(CEventHandler& EventHandlerRef, CServerConfig& ConfigRef, UInt uRank) OVERRIDE;
    virtual void   Exit(void) OVERRIDE;

    virtual bool   Start(void) OVERRIDE;
    virtual void   Stop(bool bUnlink) OVERRIDE;

    virtual CServerConfig&    GetConfig(void) OVERRIDE;
    virtual CEventHandlerPtr& GetMgrHandler(void) OVERRIDE;
    virtual CNetworkPtr&      GetNetworkPtr(void) OVERRIDE;
    virtual CFileLogPipe&     GetFileLog(void) OVERRIDE;
    virtual CSignalEvent&     GetSignalEvent(void) OVERRIDE;
    virtual SERVER_DATA&      GetData(void) OVERRIDE;
    virtual SERVER_CLUSTER&   GetCluster(UInt uRank, bool bLocal = true) OVERRIDE;
    // CPAKHandler
    virtual bool   OnTcpDispatch(const PacketPtr& PktPtr, PTCP_PARAM pTcp) OVERRIDE;
    virtual bool   OnTcpAccept(Socket_t sAccept, Socket_t sListen) OVERRIDE;
    virtual bool   OnTcpClose(Socket_t sSocket, ULLong ullLiveData) OVERRIDE;
    // CEventHandler
    virtual UInt   OnHandle(uintptr_t utEvent, UInt uCount) OVERRIDE;
private:
    CMasterServer(const CMasterServer&);
    CMasterServer& operator=(const CMasterServer&);
    // 从配置加载数据
    bool  LoadConfig(void);
    // 清除从配置加载的数据
    void  UnloadConfig(void);
    // 按配置信息加载业务层
    bool  LoadRoutine(void);
    // 释放加载的业务层
    void  UnloadRoutine(void);

    bool  StartListen(void);
    void  CheckListen(void);
    void  StopListen(void);

    void  CheckUpdate(void);
    // 按层级从小向大同步服务信息
    void  SyncUpdate(void);
    void  SyncServer(UInt uRank);

    bool  OnCommonEvent(UInt uRank, const PacketPtr& PktPtr, Socket_t sSocket);

    bool  OnLink(UInt uRank, Socket_t sSocket, CNETHead* pLink);
    bool  OnUpdate(UInt uRank, Socket_t sSocket, CNETHead* pUpdate);
    bool  OnSync(UInt uRank, Socket_t sSocket, CPAKHead* pSync);
    bool  OnUnlink(UInt uRank, Socket_t sSocket, CPAKHead* pHead);

    // 注册服务
    bool  LinkServer(UInt uRank, Socket_t sSocket, CNETHead* pLink);
    // 更新服务
    bool  UpdateServer(UInt uRank, Socket_t sSocket, CNETHead* pUpdate);
    // 同步服务
    bool  SyncServer(UInt uRank, Socket_t sSocket, CPAKHead* pSync);
    // 注销服务
    bool  UnlinkServer(UInt uRank, Socket_t sSocket, UInt uType);

    bool  AddSync(UInt uRank, UInt uSync, Socket_t sSocket);
    bool  RemoveSync(UInt uRank, UInt uSync, Socket_t sSocket);

    bool  SyncServerPack(SERVER_CLUSTER& Cluster, PINDEX& index, ARY_SYNC& aSocket, UInt uRank);
    bool  SyncServerPack(SERVER_CLUSTER& Cluster, PINDEX& index, Socket_t sSocket, UInt uRank);
private:
    CServerConfig*     m_pConfig;
    CFileLogPipe       m_FileLog;
    CEventHandlerPtr   m_MgrHandler;
    CNetworkPtr        m_NetworkPtr;
    CRoutinePtr        m_RoutinePtr;
    SERVER_DATA        m_SrvData;

    SERVER_CLUSTER     m_Cluster[COMMONR_MAX];
    SERVER_SYNC        m_Sync[COMMONR_MAX];
};

INLINE CMasterServer::CMasterServer(void)
: m_pConfig(nullptr)
, m_FileLog(false)
{
}

INLINE CMasterServer::~CMasterServer(void)
{
}

INLINE CMasterServer::CMasterServer(const CMasterServer&)
: m_pConfig(nullptr)
, m_FileLog(false)
{
}

INLINE CMasterServer& CMasterServer::operator=(const CMasterServer&)
{
    return (*this);
}

INLINE CServerConfig& CMasterServer::GetConfig(void)
{
    return (*m_pConfig);
}

INLINE CEventHandlerPtr& CMasterServer::GetMgrHandler(void)
{
    return m_MgrHandler;
}

INLINE CNetworkPtr& CMasterServer::GetNetworkPtr(void)
{
    return m_NetworkPtr;
}

INLINE CFileLogPipe& CMasterServer::GetFileLog(void)
{
    return m_FileLog;
}

INLINE CSignalEvent& CMasterServer::GetSignalEvent(void)
{
    return Events;
}

INLINE SERVER_DATA& CMasterServer::GetData(void)
{
    return m_SrvData;
}

INLINE SERVER_CLUSTER& CMasterServer::GetCluster(UInt uRank, bool)
{
    if (uRank < COMMONR_MAX)
    {
        return m_Cluster[uRank];
    }
    return m_Cluster[COMMONR_MASTER];
}

#endif // __MASTER_SERVER_H__
